package com.github.thinwonton.spring.aop.aspect.anno;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
public class UserServiceAspect {
    @Pointcut("execution(* com.github.thinwonton.spring.aop.service.*.*(..))")
    public void pointCut() {
    }

    @After("pointCut()")
    public void after() {
        System.out.println("after aspect executed");
    }

    @Before("pointCut()")
    public void before() {
        System.out.println("before aspect executing");
    }

    @AfterReturning(pointcut = "pointCut()", returning = "returnVal")
    public void afterReturning(JoinPoint joinPoint, Object returnVal) {
        System.out.println("afterReturning executed, return result is "
                + returnVal);
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("around start..");

        //访问目标方法的参数：
        Object[] args = joinPoint.getArgs();
        Object returnValue = null;
        try {
            returnValue = joinPoint.proceed(args);
        } catch (Exception ex) {
            System.out.println("error in around");
            throw ex;
        }
        System.out.println("around end");

        return returnValue;
    }

    @AfterThrowing(pointcut = "pointCut()", throwing = "error")
    public void afterThrowing(JoinPoint joinPoint, Throwable error) {
        System.out.println("error in AfterThrowing:" + error);
    }
}